

class SlideCode {
    constructor(props) {
        this.config = this.objectAssign(props);
        // 定义状态
        this.isSuccess = false;
        // 用于存放鼠标按下时的位置
        this.downX = 0;
        this.create();
    }

    // 创建
    create = async _ => {
        let {config} = this;
        let {dom, id, width, height} = config;
        // 创建 html css 元素
        await this.createElement(config);
        // 给滑块添加鼠标按下事件
        this.getEle(`.${id}_slider`).onmousedown = this.mousedownHandler;
    };

    // 鼠标按下事件的方法实现
    mousedownHandler = e => {
        let {id} = this.config;
        let bgColor = this.getEle(`.${id}_bgColor`);//背景色
        let slider = this.getEle(`.${id}_slider`);//滑块
        bgColor.style.transition = "";
        slider.style.transition = "";
        e = e || window.event || e.which;
        this.downX = e.clientX;
        //在鼠标按下时，分别给鼠标添加移动和松开事件
        document.onmousemove = this.mousemoveHandler;
        document.onmouseup = this.mouseupHandler;
    };

    // 鼠标移动事件的方法实现
    mousemoveHandler = (e) => {
        let {id} = this.config;
        let bgColor = this.getEle(`.${id}_bgColor`);//背景色
        let slider = this.getEle(`.${id}_slider`);//滑块
        let box = this.getEle(`#${id}_box`);
        let successMoveDistance = box.offsetWidth- slider.offsetWidth;//解锁需要滑动的距离
        e = e || window.event || e.which;
        let moveX = e.clientX;
        let offsetX = this.getOffsetX(moveX - this.downX,0,successMoveDistance);
        bgColor.style.width = offsetX + "px";
        slider.style.left = offsetX + "px";

        if(offsetX === successMoveDistance){
            this.success();
        }
        //如果不设置滑块滑动时会出现问题（目前还不知道为什么）
        e.preventDefault();
    };

    // 鼠标松开事件的方法实现
    mouseupHandler = e => {
        let {id} = this.config;
        let bgColor = this.getEle(`.${id}_bgColor`);//背景色
        let slider = this.getEle(`.${id}_slider`);//滑块
        if(!this.isSuccess){
            bgColor.style.width = 0 + "px";
            slider.style.left = 0 + "px";
            bgColor.style.transition = "width 0.8s linear";
            slider.style.transition = "left 0.8s linear";
            this.error();
        }
        document.onmousemove = null;
        document.onmouseup = null;
    };

    // 成功后的回调
    success = () => {
        let {id, success, successColor} = this.config;
        this.isSuccess = true;
        this.getEle(`.${id}_txt`).innerHTML = "解锁成功";
        this.getEle(`.${id}_bgColor`).style.backgroundColor = successColor;
        this.getEle(`.${id}_slider`).className = `${id}_slider active`;
        //滑动成功时，移除鼠标按下事件和鼠标移动事件
        this.getEle(`.${id}_slider`).onmousedown = null;
        document.onmousemove = null;
        success();
    };

    // 失败的回调
    error = () => {
        let {error} = this.config;
        error();
    };
}

// TODO 定义了一个获取元素的方法
SlideCode.prototype.getEle = selector => {
    return document.querySelector(selector);
};

// TODO 定义一个获取鼠标当前需要移动多少距离的方法
SlideCode.prototype.getOffsetX = (offset,min,max) => {
    if(offset < min){
        offset = min;
    }else if(offset > max){
        offset = max;
    }
    return offset;
};

// TODO 定义创建 html css 方法
SlideCode.prototype.createElement = data => {
    return new Promise(resolve => {
        let {dom, id, width, height, beforeColor, fontColor, sliderBackground, sliderBorderColor, underSliderBackground, fontSize} = data;
        let style = document.createElement('style');
        style.innerHTML = "#"+ id +"_box{\n" +
            "            position: relative;\n" +
            "            width: "+ width +"px;\n" +
            "            height: "+ height +"px;\n" +
            "            margin: 0 auto;\n" +
            "            background-color: "+ beforeColor +";\n" +
            "            box-shadow: 1px 1px 5px rgba(0,0,0,0.2);\n" +
            "        }\n" +
            "        ."+ id +"_bgColor{\n" +
            "            position: absolute;\n" +
            "            left:0;\n" +
            "            top:0;\n" +
            "            width:40px;\n" +
            "            height: "+ height +"px;\n" +
            "            background-color: "+ underSliderBackground +";\n" +
            "        }\n" +
            "        ."+ id +"_txt{\n" +
            "            position: absolute;\n" +
            "            width: 100%;\n" +
            "            height: "+ height +"px;\n" +
            "            line-height: "+ height +"px;\n" +
            "            font-size: "+ fontSize +"px;\n" +
            "            color: "+ fontColor +";\n" +
            "            text-align: center;\n" +
            "        }\n" +
            "        ."+ id +"_slider{\n" +
            "            position: absolute;\n" +
            "            left:0;\n" +
            "            top:0;\n" +
            "            width: 50px;\n" +
            "            height: "+ (height - 2) +"px;\n" +
            "            border: 1px solid "+ sliderBorderColor +";\n" +
            "            background: "+ sliderBackground +";\n" +
            "            text-align: center;\n" +
            "            cursor: move;\n" +
            "        }\n" +
            "        ."+ id +"_slider>svg{" +
            "            width: 25px;" +
            "            height : "+ height +"px;" +
            "        }";
        document.getElementsByTagName("head").item(0).appendChild(style);
        dom.innerHTML = '' +
            '<div id="'+ id +'_box" onselectstart="return false;">' +
            '<div class="'+ id +'_bgColor"></div>' +
            '<div class="'+ id +'_txt" >滑动解锁</div>' +
            '<div class="'+ id +'_slider">' +
            '<svg t="1602565210547" class="icon" viewBox="0 0 1109 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5105" width="200" height="200"><path fill="#000" id="'+ id +'_slider_svg" d="M612.266667 108.885333a29.952 29.952 0 0 0 0 42.410667l381.781333 381.866667a29.952 29.952 0 0 0 42.410667-42.410667L654.677333 108.970667a29.866667 29.866667 0 0 0-42.410666-0.085334z m381.866666 380.842667l-381.952 381.952a29.952 29.952 0 0 0 42.410667 42.410667l381.952-381.952a29.952 29.952 0 0 0-42.410667-42.410667zM158.293333 108.885333a29.952 29.952 0 0 0 0 42.410667L540.16 533.162667a29.952 29.952 0 0 0 42.410667-42.410667L200.704 108.970667a29.866667 29.866667 0 0 0-42.410667-0.085334zM540.16 489.728l-381.952 381.952a29.952 29.952 0 0 0 42.410667 42.410667l381.952-381.952a29.952 29.952 0 0 0-42.410667-42.410667z" p-id="5106"></path></svg>' +
            '</div>' +
            '</div>';
        document.getElementById(id +'_slider_svg').setAttribute("fill",fontColor);
        resolve();
    })
};

// TODO 合并配置
SlideCode.prototype.objectAssign = (props) => {
    if(!props || typeof props !== 'object'){
        props = {}
    }
    let config = {
        // [非必传] 宽度
        width : 300,
        // [非必传] 高度
        height : 40,
        // [非必传] 未滑动的背景色
        beforeColor : '#e8e8e8',
        // [非必传] 成功后的背景色
        successColor : '#90ee90',
        // [非必传] 文字颜色
        fontColor : '#000',
        // [f非必传] 文字大小
        fontSize : 14,
        // [非必传] 滑块的背景颜色
        sliderBackground : '#fff',
        // [非必传] 滑块边框色
        sliderBorderColor: '#ccc',
        // [非必传] 已经滑过的背景色
        underSliderBackground :'#add8e6',
        // [非必传] 失败回调函数 每次滑动失败都会有一次调用
        error : () => {},
    };
    if(!props.dom){
        console.error('dom元素不正确，已自动切换至body标签！');
        props.dom = document.getElementsByTagName('body')[0];
    }

    if(!props.id || typeof props.id !== 'string'){
        props.id = 'A_' + new Date().getTime();
        console.error(`id值不存在或不是一个字符串类型，已自动生成值为：${props.id}`);
    }

    if(!props.success || typeof props.success !== 'function'){
        props.success = () => {
            console.error('当前滑动已成功，但没有设置成功的回调函数！');
        };
        console.error(`success字段不存在或不是一个函数！`);
    }
    return Object.assign(config, props)
};


module.exports = SlideCode;
